package liming.ai.client.impl.deepseek;

import liming.ai.client.AbstractClient;
import liming.ai.core.AbstractCore;
import liming.ai.core.ResponseInterface;
import liming.ai.core.impl.deepseek.DeepSeekConfig;
import liming.ai.core.impl.deepseek.DeepSeekCore;
import liming.ai.data.AbstractRequest;
import liming.ai.data.deepseek.Answer;
import liming.ai.data.deepseek.ChatCompletionRequest;
import liming.ai.data.deepseek.Message;
import liming.tool.file.FileRW;
import liming.tool.lock.CodeCondition;
import liming.tool.lock.CodeLock;
import liming.tool.runnable.HandRunnable;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class DeepSeekClient implements AbstractClient {
    //格式化时间，为YYYY_MM_DD_HH_mm_ss:sss
    private static final String TIME_FORMAT = "yyyy_MM_dd_HH_mm_ss_SSS";
    // 新增时间格式化方法
    protected static String getFormattedTimestamp() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(TIME_FORMAT);
        return LocalDateTime.now().format(formatter);
    }


    protected File file = new File("./query/"+getFormattedTimestamp()+"/");

    protected ChatCompletionRequest request = new ChatCompletionRequest();
    protected AbstractCore core;
    protected DeepSeekConfig config;
    public DeepSeekClient(File configFile) throws IOException {
        config = new DeepSeekConfig();
        if(configFile.exists()){
            JSONObject jsonObject = new JSONObject(FileRW.readTextFile(configFile).toString());
            if(config.initConfig(jsonObject))
                FileRW.writeTextFile(configFile, jsonObject.toString(),false);
        }else {
            FileRW.writeTextFile(configFile,new JSONObject().put("deepseek",config.toJSON()).toString(),false, FileRW.FileEncoding.UTF8);
            System.exit(0);
        }
        core = new DeepSeekCore(config,getInterceptor());
        String title = config.getTitle();
        if(!title.isEmpty())
            request.addMessage(new Message(Message.Role.SYSTEM,title));
    }

    public DeepSeekConfig getConfig() {
        return config;
    }

    protected Interceptor getInterceptor(){
        return new Interceptor(){
            @NotNull
            @Override
            public Response intercept(@NotNull Chain chain) throws IOException {
                Request request = chain.request();
                AtomicInteger retryCount = new AtomicInteger(0);

                while (true) {
                    try {
                        Response response = chain.proceed(request);
                        if (retryCount.get() > 0 && response.isSuccessful()) {
                            System.out.println("重试成功，第 " + retryCount.get() + " 次重试");
                        }
                        return response;
                    } catch (IOException e) {
                        if (retryCount.get() >= config.getMaxRetries()
                                || !isRetryableException(e)) {
                            throw e;
                        }

                        long waitTime = (long) (config.getInitialTimeOut() * Math.pow(2, retryCount.get()));
                        System.out.println("请求失败，等待 " + waitTime + "ms 后重试 ("
                                + (retryCount.get()+1) + "/" + config.getMaxRetries() + ")");

                        try {
                            TimeUnit.MILLISECONDS.sleep(waitTime);
                        } catch (InterruptedException ignored) {
                            Thread.currentThread().interrupt();
                        }
                        retryCount.incrementAndGet();
                    }
                }
            }

            private boolean isRetryableException(IOException e) {
                // 可重试的异常类型：连接超时、读取超时等
                return e instanceof java.net.SocketTimeoutException
                        || e instanceof java.net.ConnectException;
            }
        };
    }
    @Override
    public String chat(boolean keep,String question) {
        return chat(question,request);
    }
    public String chat(String question, ChatCompletionRequest request) {
        CodeCondition condition = new CodeLock().newCondition();
        Answer answer = new Answer(question);
        request.addMessage(new Message(Message.Role.USER,question));
        String q = question.replaceAll( "[\\\\/:*?\"<>|]","").replace("\n","");
        String substring = System.currentTimeMillis()+"_"+q.substring(0,Math.min(q.length(),10));
        HandRunnable.run(()->FileRW.writeTextFile(new File(file,substring+"_1_问题.txt"),question,false,config.getFileWriterEncoding()));
        core.handle(request, new ResponseInterface() {
            @Override
            public void onError(AbstractRequest request, String error) {
                answer.setAnswer("出错了（OvO） "+error);
                condition.signal();
            }

            @Override
            public void onComplete(String reasoningContent, String content) {
                System.out.println("\n=======================================");
                request.addMessage(new Message(Message.Role.ASSISTANT, content));
                try {
                    FileRW.writeTextFile(new File(file, substring +"_2_思考.txt"),reasoningContent,false,config.getFileWriterEncoding());
                    FileRW.writeTextFile(new File(file,substring +"_3_回答.md"),content,false,config.getFileWriterEncoding());
                } catch (IOException e) {
                    onError(request,FileRW.getStackTrace(e));
                }
                answer.setAnswer(content);
                answer.setReasoning(reasoningContent);
                condition.signal();
            }
        });
        condition.await();
        return answer.getAnswer();
    }

    public ChatCompletionRequest getHistory(){
        return request;
    }
}
